<template>
	<div class="Wangeditor-box">
		<Toolbar class="Wangeditor-Toolbar" :editor="editorRef" :defaultConfig="toolbarConfig" :mode="mode" />
		<Editor
			class="Wangeditor-Editor"
			v-model="editValue"
			:defaultConfig="editorConfig"
			:mode="mode"
			@onCreated="handleCreated"
			@onChange="handleChange"
			@customPaste="customPaste"
		/>
	</div>
</template>
<script setup>
// 文档地址：https://www.wangeditor.com/v5/for-frame.html
import '@wangeditor/editor/dist/css/style.css'; // 引入 css
import { Editor, Toolbar } from '@wangeditor/editor-for-vue';
import { Boot } from '@wangeditor/editor';
import attachmentModule from '@wangeditor/plugin-upload-attachment'; //附件上传插件（如果项目不需要使用则注释相关代码）
import { onBeforeUnmount, shallowRef, getCurrentInstance, computed } from 'vue';
import { ElMessage } from 'element-plus';
import axios from 'axios';

const props = defineProps({
	mode: {
		default: 'default', // default：默认展示全部菜单；simple：精简模式
		type: String
	},
	modelValue: {
		type: String,
		default: ''
	},
	token: {
		type: String,
		default: ''
	},
});

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();

const editValue = computed({
	get() {
		return props.modelValue;
	},
	set(value) {
		// emits('update:modelValue', value);
	}
});

const emits = defineEmits(['update:modelValue']);

// 注册。要在创建编辑器之前注册，且只能注册一次，不可重复注册。(这里用于附件上传插件的注册，如果不需要则注释)
if (Boot.plugins.length < 13) {
	//判断如果已经插入进去，不在二次插入
	Boot.registerModule(attachmentModule);
}

const toolbarConfig = {
	insertKeys: {
		index: 21, // 自定义插入的位置
		keys: ['uploadAttachment'] // “上传附件”菜单
	},
	excludeKeys:["blockquote","bulletedList","numberedList","todo","insertLink","uploadAttachment","insertVideo","insertTable","codeBlock","undo","redo","fullScreen","bgColor","clearStyle"]
};

// 编辑器配置
const editorConfig = {
	placeholder: '请输入内容...',
	autoFocus: false,
	// 在编辑器中，点击选中“附件”节点时，要弹出的菜单
	/* hoverbarKeys: {
		attachment: {
			menuKeys: ['downloadAttachment'] // “下载附件”菜单
		}
	}, */
	// 所有的菜单配置，都要在 MENU_CONF 属性下
	MENU_CONF: {
		// 配置图片上传
		uploadImage: {
			server: '/api/common/upload-file?module=enterprise&size=10', //上传接口地址
			headers: {
				Authorization: props.token
			},
			metaWithUrl: true, // 参数拼接到 url 上
			fieldName: 'file', //上传文件名
			methods: 'post',
			allowedFileTypes: ['image/*'],
			maxFileSize: 10 * 1024 * 1024, // 10M 单个文件的最大体积限制，默认为 2M
			onSuccess(file, res) {
				if (res.code == 200) {
					ElMessage.success(`${file.name} 上传成功`);
				} else {
					ElMessage.error(res.msg || '上传失败');
				}
			},
			onFailed(file, res) {
				if (res.code == 200) {
					ElMessage.success(`${file.name} 上传成功`);
				} else {
					ElMessage.error(res.msg || '上传失败');
				}
			},
			// 上传错误，或者触发 timeout 超时
			onError(file, err, res) {
				if (file.size / 1024 / 1024 > 10) {
					ElMessage.warning('上传文件超过10M');
					return;
				}
				ElMessage.error(res.msg || '上传失败');
			},
			customInsert(res, insertFn) {
				if (res.code == 200) {
					insertFn(res.data.absolutePath);
				}
			}
		},
		// 配置视频上传
		uploadVideo: {
			server: '/api/common/upload-file?module=enterprise&size=100', //上传接口地址
			headers: {
				Authorization: props.token
			},
			// maxNumberOfFiles: 1, // 最多可上传几个文件，默认为 5
			fieldName: 'file', //上传文件名
			maxFileSize: 100 * 1024 * 1024, // 100M 单个文件的最大体积限制，默认为 2M
			onSuccess(file, res) {
				if (res.code == 200) {
					ElMessage.success(`${file.name} 上传成功`);
				} else {
					ElMessage.error(res.msg || '上传失败');
				}
			},
			onFailed(file, res) {
				if (res.code == 200) {
					ElMessage.success(`${file.name} 上传成功`);
				} else {
					ElMessage.error(res.msg || '上传失败');
				}
			},
			// 上传错误，或者触发 timeout 超时
			onError(file, err, res) {
				if (file.size / 1024 / 1024 > 100) {
					ElMessage.warning('上传文件超过100M');
					return;
				}
				ElMessage.error(res.msg || '上传失败');
			},
			customInsert(res, insertFn) {
				if (res.code == 200) {
					insertFn(res.data.absolutePath);
				}
			}
		},
		// 附件上传
		uploadAttachment: {
			server: '/api/common/upload-file?module=enterprise&size=10', // 服务端地址
			timeout: 10 * 1000, // 5s
			fieldName: 'file',
			headers: {
				Authorization: props.token
			},
			maxFileSize: 10 * 1024 * 1024, // 10M
			onSuccess(file, res) {
				if (res.code == 200) {
					ElMessage.success(`${file.name} 上传成功`);
				} else {
					ElMessage.error(res.msg || '上传失败');
				}
			},
			onFailed(file, res) {
				if (res.code == 200) {
					ElMessage.success(`${file.name} 上传成功`);
				} else {
					ElMessage.error(res.msg || '上传失败');
				}
			},
			// 上传错误，或者触发 timeout 超时
			onError(file, err, res) {
				if (file.size / 1024 / 1024 > 10) {
					ElMessage.warning('上传文件超过10M');
					return;
				}
				ElMessage.error(res.msg || '上传失败');
			},
			customInsert(res, file, insertFn) {
				if (res.code == 200) {
					ElMessage.success(`${file.name} 上传成功`);
					insertFn(`附件-${file.name}`, res.data.absolutePath);
				} else {
					ElMessage.error(res.msg || '上传失败');
				}
			},
			// 插入到编辑器后的回调
			onInsertedAttachment(elem) {
				// console.log('inserted attachment', elem);
			}
		}
	}
};

const handleCreated = (editor) => {
	editorRef.value = editor; // 记录 editor 实例，重要！
};

// 内容改变
const handleChange = (editor) => {
	if (editor.getText().length > 10000) {
		console.log('文本超长');
	}
	emits('update:modelValue', editor.getHtml());
};

// 粘贴事件
const customPaste = (editor, event, callback) => {
	// 去掉格式
	const text = event.clipboardData.getData('text/plain'); // 获取粘贴的纯文本
	editor.insertText(text);
	event.preventDefault();
	callback(false);
};

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
	const editor = editorRef.value;
	if (editor == null) return;
	editor.destroy();
});
</script>

<style lang="scss">
.Wangeditor-box {
	width: 100%;
	min-height: 100%;
	display: flex;
	flex-direction: column;
	border: 1px solid #ebeef5;

	.Wangeditor-Toolbar {
		border-bottom: 1px solid #ebeef5;
	}

	.Wangeditor-Editor {
		min-height: 310px;
		flex: 1;
	}
}
</style>
